home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume2 / xbrowser / part01 next >
Encoding:
Internet Message Format  |  1989-01-03  |  54.7 KB

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v02i069:  a browser, Part01/03
  5. Message-ID: <1953@wyse.wyse.com>
  6. Date: 3 Jan 89 20:52:50 GMT
  7. Organization: Wyse Technology, San Jose
  8. Lines: 2076
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: Schlichter.Wbst@Xerox.COM (Hans Schlichter)
  12. Posting-number: Volume 2, Issue 69
  13. Archive-name: xbrowser/part01
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 1 (of 3)."
  22. # Contents:  README commands.c search.c util.c xbrowser.man
  23. # Wrapped by mikew@wyse on Tue Jan  3 12:03:47 1989
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'README' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'README'\"
  27. else
  28. echo shar: Extracting \"'README'\" \(1181 characters\)
  29. sed "s/^X//" >'README' <<'END_OF_FILE'
  30. XXbrowser provides a graphical interface to browse directories, 
  31. Xselect files from directory listings and invoke commands on them,
  32. Xsuch as invoking the editor on these files,
  33. Xsearch files for specified patterns, move, copy or delete files.
  34. X
  35. XXbrowser was developed for X11 R3. It runs on Sun workstations
  36. Xunder Sun OS 3.2, 3.5 and 4.0. I did not test it on any
  37. Xother workstation type. Portability was not a major concern
  38. Xduring development. I only wanted to learn X11 and the X11 Toolkit.
  39. XTherefore I used both regular expression packages of SUN OS
  40. X(regexp and regex) which might not be available on other Unix versions.
  41. X
  42. XI tested xbrowser with the following window managers: wm, rtl, uwm and
  43. Xtwm. A special warning if you use twm: your .twmrc must set 
  44. XNoTitleFocus otherwise the dialog boxes and the text windows do not work
  45. Xcorrectly. I believe there is a bug in twm.
  46. X
  47. XAnother warning:
  48. XIf you specify a geometry resource for xbrowser
  49. Xin your .Xdefaults file, the dialog boxes will have initially these geometry
  50. Xsizes (you might have very strange shaped command buttons). Geometry values
  51. Xspecified on the command line which called xbrowser 
  52. Xdo not affect the dialog box geometry.
  53. X
  54. END_OF_FILE
  55. if test 1181 -ne `wc -c <'README'`; then
  56.     echo shar: \"'README'\" unpacked with wrong size!
  57. fi
  58. # end of 'README'
  59. fi
  60. if test -f 'commands.c' -a "${1}" != "-c" ; then 
  61.   echo shar: Will not clobber existing file \"'commands.c'\"
  62. else
  63. echo shar: Extracting \"'commands.c'\" \(18919 characters\)
  64. sed "s/^X//" >'commands.c' <<'END_OF_FILE'
  65. X/* Systems Sciences Laboratory, Webster Research Center */
  66. X
  67. Xstatic char *PROGRAM_information[] =
  68. X{
  69. X    "Copyright (c) 1988 Xerox Corporation.  All rights reserved.",
  70. X    "$Header$",
  71. X    "$Locker$"
  72. X}
  73. X;
  74. X
  75. X/*
  76. X * Copyright protection claimed includes all forms and matters of copyrightable
  77. X * material and information now allowed by statutory or judicial lay or
  78. X * herinafter granted, including without limitation, material generated from
  79. X * the software programs which are displayed on the screen such as icons,
  80. X * screen display looks, etc.
  81. X */
  82. X
  83. X
  84. X#include "xfilebrowser.h"
  85. X#include <ctype.h>
  86. X#include <sys/file.h>
  87. X
  88. Xextern char *getenv();
  89. Xextern char *re_comp();
  90. X
  91. Xtypedef enum { JHSXEDIT, EMACS, VI, XEDIT, XMORE, ED_UNKNOWN } edittype;
  92. Xtypedef enum { DELETE, MOVE, COPY } requesttype;
  93. X
  94. Xstatic DialogData dialogdata;
  95. Xstatic unsigned int cmdsize = 1024;
  96. X
  97. X
  98. XDoQuit()
  99. X{
  100. X    XtUnmapWidget(toplevel);
  101. X    XCloseDisplay(curdisplay);
  102. X    exit(0);
  103. X}
  104. X
  105. X/* ARGSUSED */
  106. Xsetup_pattern(source, pattern)
  107. Xchar *source, *pattern;
  108. X{
  109. X    register char *p = source;
  110. X    register char *q = pattern;
  111. X    
  112. X    *q = '^'; q++;
  113. X    while (*p != '\0') {
  114. X       if (*p == '.') { *q = '\\'; q++; *q = '.'; }
  115. X       else if (*p == '$') *q = '.';
  116. X       else if (*p == '*') { *q = '.'; q++; *q = '*'; }
  117. X       else *q = *p; 
  118. X
  119. X       q++; p++;
  120. X    }
  121. X    *q = '$'; q++; *q = '\0';
  122. X}
  123. X
  124. X/* ARGSUSED */
  125. XDoList(w, client_data, call_data)
  126. XWidget w;
  127. Xcaddr_t client_data, call_data;
  128. X{
  129. X    int i;
  130. X    char *error;
  131. X    char tmppattern[64], curpattern[255];
  132. X    XtTextPosition pos1, pos2;
  133. X    short dir;
  134. X    struct stat buf;
  135. X
  136. X    switch ((int)call_data) {
  137. X       case 2: dir = -1; break;
  138. X       case 3: 
  139. X        if (!check_option()) display_listoptions(w); 
  140. X        return;
  141. X
  142. X       case 0:
  143. X       case 1: 
  144. X       default: dir = (short)call_data; break;
  145. X    }
  146. X
  147. X    XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  148. X    if (pos1 != pos2 && numfiles != 0 && 
  149. X        ( (i = select_file(pos1, pos2)) != -1)) {
  150. X       if (stat((*files[i]).d_name, &buf) == -1) {
  151. X         disp_message("\nList: cannot check file stats");
  152. X            return;
  153. X        }
  154. X        if (buf.st_mode & S_IFDIR) 
  155. X            sprintf(curpattern, "%s/%s", (*files[i]).d_name, filepattern);
  156. X        else {
  157. X            disp_message(
  158. X       "\nList: selected file %s is not a directory\nuse current pattern",
  159. X                (*files[i]).d_name);
  160. X        if (! strcmp(filepattern, oldpattern)) return;
  161. X            else strcpy(curpattern, filepattern);
  162. X       }
  163. X    }
  164. X    else strcpy(curpattern, filepattern);
  165. X
  166. X    if (strcmp(curpattern, oldpattern)) {
  167. X        /* old pattern and new pattern differ */
  168. X       if (get_dirpat(curpattern, curdirectory, oldpattern) == -1) {
  169. X           disp_message("\nList: access to directory?");
  170. X           return;
  171. X       }
  172. X    }
  173. X    
  174. X    setup_pattern(oldpattern, tmppattern);
  175. X    if (error = re_comp(tmppattern)) {
  176. X       disp_message("\nList: search pattern %s?", error);
  177. X       return;
  178. X    }
  179. X
  180. X    clear_widget(grepwidget, grepsource);
  181. X    clear_widget(listwidget, listsource);
  182. X    free_direct(&files, &numfiles);
  183. X    free_hitfiles();
  184. X
  185. X    if (prepare_list(curdirectory, dir, &files, &numfiles, 
  186. X            (char *)NULL) != -1) {
  187. X       if (!(chdir(curdirectory))) {
  188. X           strcpy(filepattern, oldpattern);
  189. X           setup_dirlabel(curdirectory, oldpattern);
  190. X       }
  191. X       else disp_message("\nList: problems in changing to %s",
  192. X             curdirectory);
  193. X       display_files(0);
  194. X    }
  195. X    else clear_widget(listwidget, listsource);
  196. X
  197. X    setup_iconname();
  198. X
  199. X    return;
  200. X}
  201. X
  202. X
  203. X/***************************
  204. X*     Edit Routines 
  205. X****************************/
  206. X
  207. X/* ARGSUSED */
  208. Xedittype check_editor(s)
  209. Xchar *s;
  210. X{
  211. X    char *p, *q;
  212. X    int len;
  213. X    edittype result;
  214. X    
  215. X    p = s; result = ED_UNKNOWN;
  216. X    while ( p != NULL) {
  217. X       if ( (q = index(p, ' ')) != NULL) len = q - p;
  218. X       else len = strlen(p);
  219. X
  220. X       if (! strncmp(p, "jhsxedit", len)) { result = JHSXEDIT; break; }
  221. X       else if (! strncmp(p, "xedit", len)) { result = XEDIT; break; }
  222. X       else if (! strncmp(p, "emacs", len)) { result = EMACS; break; }
  223. X       else if (! strncmp(p, "vi", len)) { result = VI; break; }
  224. X       else if (! strncmp(p, "xmore", len)) { result = XMORE; break; }
  225. X
  226. X       if (q != NULL) {
  227. X        q++;
  228. X           while (*q == ' ') q++;
  229. X           p = q;
  230. X       }
  231. X       else break;
  232. X    }
  233. X    
  234. X    return result;
  235. X}
  236. X
  237. X/* ARGSUSED */
  238. Xinvoke_editor(file, toline, edit)
  239. Xchar *file;
  240. Xint toline;
  241. XBoolean edit;
  242. X{
  243. X    int cc;
  244. X    char command[255];
  245. X    char *editor = NULL, *curviewer;
  246. X    struct stat buf;
  247. X    edittype edit_view;
  248. X    static char xviewer[] = "xmore";
  249. X    static char xeditor[] = "xedit";
  250. X    
  251. X    if (stat(file, &buf) == -1) {
  252. X        disp_message("\nEdit: cannot check file stats");
  253. X        return;
  254. X     }
  255. X
  256. X     if ( (buf.st_mode & S_IFMT) == S_IFREG ) {
  257. X       if (!edit) {
  258. X        edit_view = XMORE;
  259. X        curviewer = &xviewer[0];
  260. X       }
  261. X       else {
  262. X            if ( (editor = getenv("XEDITOR")) != NULL) {
  263. X           edit_view = check_editor(editor);
  264. X           curviewer = editor;
  265. X        }
  266. X        else {
  267. X           edit_view = XEDIT;
  268. X           curviewer = &xeditor[0];
  269. X        }
  270. X       }
  271. X
  272. X          if (toline != 0) {
  273. X            switch(edit_view) {
  274. X               case JHSXEDIT:
  275. X               case EMACS:
  276. X               case VI:
  277. X                   sprintf(command, "%s -display %s +%d %s&", 
  278. X               curviewer, DisplayString(curdisplay), toline, file);
  279. X                   break;
  280. X               default:
  281. X                   sprintf(command, "%s -display %s %s&",
  282. X                          curviewer, DisplayString(curdisplay), file);
  283. X                   break;
  284. X        }
  285. X        }
  286. X       else sprintf(command, "%s -display %s %s&", 
  287. X                curviewer, DisplayString(curdisplay), file);
  288. X       cc = system(command);
  289. X    }
  290. X    else disp_message("\nEdit: %s not regular file!", file);    
  291. X}
  292. X
  293. XDoEdit(w, client_data, call_data)
  294. XWidget w;
  295. Xcaddr_t client_data, call_data;
  296. X{
  297. X    XtTextPosition pos1, pos2;
  298. X    int i;
  299. X
  300. X    if ( (int)call_data == 3 ) return;
  301. X    XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  302. X    if (pos1 == pos2 || numfiles == 0) {
  303. X        disp_message("\nEdit: no file selected");
  304. X        return;
  305. X     }
  306. X
  307. X    if ( (i = select_file(pos1, pos2)) == -1) {
  308. X        disp_message("\nEdit: file selection?");
  309. X        return;
  310. X     }
  311. X
  312. X    switch ( (int)call_data ) {
  313. X    case 1:    invoke_editor(files[i]->d_name, 0, False); break;
  314. X    case 2:    invoke_editor(files[i]->d_name, 0, True); break;
  315. X    }
  316. X
  317. X    return;
  318. X}
  319. X
  320. X
  321. X/***************************
  322. X*     Grep/GrepEdit Routines 
  323. X****************************/
  324. X
  325. XDoGrepEdit(w, client_data, call_data)
  326. XWidget w;
  327. Xcaddr_t client_data, call_data;
  328. X{
  329. X    XtTextPosition pos1, pos2;
  330. X    int i, linenr;
  331. X
  332. X    if ( (int)call_data == 3 ) return;
  333. X
  334. X    XtTextGetSelectionPos(grepwidget, &pos1, &pos2);
  335. X    if (pos1 == pos2 || numhitfiles == 0) {
  336. X        disp_message("\nEdit: no file selected");
  337. X        return;
  338. X     }
  339. X
  340. X    if ( (i = select_searchfile(pos1, pos2, &linenr)) == -1) {
  341. X        disp_message("\nEdit: file selection?");
  342. X        return;
  343. X     }
  344. X    switch ( (int)call_data ) {
  345. X    case 1:    invoke_editor(hitfiles[i]->name, linenr, False); break;
  346. X    case 2:    invoke_editor(hitfiles[i]->name, linenr, True); break;
  347. X    }
  348. X
  349. X    return;
  350. X}
  351. X
  352. X
  353. XDoGrep(w, client_data, call_data)
  354. XWidget w;
  355. Xcaddr_t client_data, call_data;
  356. X{
  357. X    XtTextPosition pos1, pos2, fstart, fend;
  358. X    Boolean stopwhenfound = False;
  359. X
  360. X    switch ((int)call_data) {
  361. X       case 3: 
  362. X        if (!check_search()) display_searchoptions(w); 
  363. X        return;
  364. X
  365. X       case 2:    stopwhenfound = True; break;
  366. X       case 1:    break;
  367. X       default:    return;
  368. X    }
  369. X
  370. X    if (numfiles == 0) {
  371. X       disp_message("\nGrep: no files listed");
  372. X       return;
  373. X    }
  374. X    
  375. X    if (strlen(searchpattern) == 0) {
  376. X       disp_message("\nGrep: search pattern?");
  377. X       return;
  378. X    }
  379. X    if (index(searchpattern, '\n') != NULL) {
  380. X       disp_message("\nGrep: search pattern contains newline");
  381. X       return;
  382. X    }
  383. X
  384. X    clear_widget(grepwidget, grepsource);
  385. X    free_hitfiles();
  386. X
  387. X    XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  388. X    if (pos1 == pos2 ||
  389. X        select_files(pos1, pos2, &fstart, &fend) == -1) 
  390. X       { fstart = 0; fend = numfiles -1; }
  391. X
  392. X    examine_files(fstart, fend, stopwhenfound);
  393. X}
  394. X
  395. X
  396. X/***************************
  397. X*     Shell Routines 
  398. X****************************/
  399. X
  400. X/* ARGSUSED */
  401. Xint execute_cmdline(command, saveout, savediag)
  402. Xchar *command;
  403. XBoolean saveout, savediag;
  404. X{
  405. X    int cc, i;
  406. X    int cmdindex = 0;
  407. X    struct stat statbuf;
  408. X    FILE *fin;
  409. X    char tmpfile[16];
  410. X    char buf[128];
  411. X    char *cmd = command;
  412. X
  413. X    if (saveout || savediag) {
  414. X       cmdindex = strlen(cmd);
  415. X       sprintf(tmpfile, "/tmp/xbXXXXXX");
  416. X       if (mktemp(tmpfile) == NULL) {
  417. X           disp_message("\ncannot create log file");
  418. X           return(-1);
  419. X       }
  420. X
  421. X       strcat(cmd, (savediag) ? " 2>" : " 1>");
  422. X       strcat(cmd, tmpfile);
  423. X       if (savediag && saveout) strcat(cmd, " 1>&2");
  424. X    }
  425. X    else *tmpfile = '\0';
  426. X
  427. X    cc = system(cmd);
  428. X    if (cc != 0)
  429. X       disp_message(
  430. X        "\nexit status is %d\ncheck command or targetfile",
  431. X         cc);
  432. X
  433. X    if (*tmpfile != '\0' && stat(tmpfile, &statbuf) == 0) {
  434. X          if (statbuf.st_size > 0) {
  435. X             if (statbuf.st_size < 127) {
  436. X                 fin = fopen(tmpfile, "r");
  437. X                 i = fread(buf, 1, 127, fin);
  438. X                 fclose(fin);
  439. X                 buf[i] = '\0';
  440. X                 disp_message("\n%s", buf);
  441. X          }
  442. X          else {
  443. X              command[cmdindex] = '\0'; 
  444. X            /* delete tmpfile name from command */
  445. X              log_popup(command, tmpfile);
  446. X              }
  447. X       }
  448. X       unlink(tmpfile);
  449. X    }
  450. X    
  451. X    XtTextUnsetSelection(listwidget);
  452. X    return(cc);
  453. X}
  454. X
  455. X
  456. Xshellcancel(clientdata)
  457. XDialogData *clientdata;
  458. X{
  459. X    return;
  460. X}
  461. X
  462. X/* ARGSUSED */
  463. Xshellok(clientdata)
  464. XDialogData *clientdata;
  465. X{
  466. X    char *answer = clientdata->answer;
  467. X    char *tilde, *expand, *begquote, *endquote;
  468. X
  469. X    if ( (tilde = index(answer, '~')) != NULL) {
  470. X        /* check if tilde is between single quotes; then do not
  471. X        expand tilde */
  472. X       if ( ((begquote = index(answer, '\'')) == NULL) ||
  473. X           ((endquote = index(begquote+1, '\'')) == NULL) ||
  474. X           (tilde < begquote || tilde > endquote)) {
  475. X
  476. X           if ( (expand = expand_tilde(tilde)) == NULL) {
  477. X              disp_message("\ncannot expand ~");
  478. X              return;
  479. X        }
  480. X           strcpy(tilde, expand);    /* replaces tilde by the actual
  481. X                path name */
  482. X           XtFree(expand);
  483. X       }
  484. X    }
  485. X
  486. X    execute_cmdline(answer, clientdata->out, clientdata->diag);
  487. X    return;
  488. X}
  489. X
  490. X/* ARGSUSED */
  491. XDoShell(w, client_data, call_data)
  492. XWidget w;
  493. Xcaddr_t client_data, call_data;
  494. X{
  495. X    char command[64];
  496. X    char label[32];
  497. X    char *defvalue;
  498. X    XtTextPosition pos1, pos2, fstart, fend;
  499. X    int i, len = 0;
  500. X
  501. X    switch ((int)call_data) {
  502. X       case 2:     sprintf(command, "xterm -display %s &",
  503. X                   DisplayString(curdisplay));
  504. X            system(command);
  505. X            break;
  506. X       case 1: 
  507. X            if (check_prompt() == -1) return;
  508. X                /* there is already a prompt window */    
  509. X            XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  510. X            if (pos1 != pos2 && 
  511. X               select_files(pos1, pos2, &fstart, &fend) != -1) {
  512. X               if ( (fend - fstart + 1) == numfiles) {
  513. X                defvalue = XtMalloc(255);
  514. X                strcpy(defvalue, oldpattern);
  515. X               }
  516. X               else {
  517. X                      for (i = fstart; i <= fend; i++)
  518. X                         len += files[i]->d_namlen;
  519. X                   defvalue = XtCalloc(len + (fend - fstart) + 64);
  520. X                   for (i = fstart; i <= fend; i++) {
  521. X                      strcat(defvalue, " ");
  522. X                      strcat(defvalue, files[i]->d_name);
  523. X                   }
  524. X               }
  525. X            }
  526. X            else defvalue = XtCalloc(255, 1);
  527. X
  528. X            dialogdata.w = w;
  529. X            dialogdata.start = 0;
  530. X            dialogdata.end = 0;
  531. X            dialogdata.current = 0;
  532. X            dialogdata.yes = shellok;
  533. X            dialogdata.no = NULL;
  534. X            dialogdata.cancel = shellcancel;
  535. X            sprintf(label, "which shell command to execute?");
  536. X            create_toggleprompt(&dialogdata, label, defvalue);
  537. X            XtFree(defvalue);
  538. X            break;
  539. X       case 3: 
  540. X       default:    break;
  541. X    }
  542. X    return;
  543. X}
  544. X
  545. X
  546. X
  547. X/***************************
  548. X*     Copy Routines 
  549. X****************************/
  550. X
  551. X/* ARGSUSED */
  552. Xcopyok(clientdata)
  553. XDialogData *clientdata;
  554. X{
  555. X    int fstart = clientdata->start;
  556. X    int fend = clientdata->end;
  557. X    int i;
  558. X    char *s = clientdata->answer;
  559. X    char *name;
  560. X
  561. X    strcpy(cmdline, "cp ");
  562. X    for (i = fstart; i <= fend; i++) {
  563. X       strcat(cmdline, "'");
  564. X       strcat(cmdline, files[i]->d_name);
  565. X       strcat(cmdline, "' ");
  566. X    }
  567. X    if (*s == '~') {
  568. X       if ( (name = expand_tilde(s)) == NULL) {
  569. X           disp_message("\nCopy: cannot expand target name");
  570. X           return;
  571. X       }
  572. X    }
  573. X    else name = s;
  574. X    strcat(cmdline, name);
  575. X
  576. X    if (execute_cmdline(cmdline, FALSE, TRUE) == 0) {
  577. X       if (fstart == fend) 
  578. X        DoList(clientdata->w, (caddr_t)clientdata, (caddr_t)0);
  579. X
  580. X        /* copied file may be in the same directory; if values
  581. X        are different assume files were copied into different
  582. X        directory */
  583. X    }
  584. X    return;
  585. X}
  586. X
  587. Xcopycancel(clientdata)
  588. XDialogData *clientdata;
  589. X{
  590. X    return;
  591. X}
  592. X
  593. X/* ARGSUSED */
  594. XDoCopy(w, client_data, call_data)
  595. XWidget w;
  596. Xcaddr_t client_data, call_data;
  597. X{
  598. X    XtTextPosition pos1, pos2, fstart, fend;
  599. X    char label[32];
  600. X    char defvalue[255];
  601. X
  602. X    if (check_prompt() == -1) return;
  603. X                /* there is already a prompt window */
  604. X    if (numfiles == 0) {
  605. X       disp_message("\nCopy: no files listed");
  606. X       return;
  607. X    }
  608. X
  609. X    XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  610. X    if (pos1 == pos2 || select_files(pos1, pos2, &fstart, &fend) == -1) {
  611. X       disp_message("\nCopy: no file selected");
  612. X       return;
  613. X    }
  614. X
  615. X    dialogdata.w = w;
  616. X    dialogdata.start = fstart;
  617. X    dialogdata.end = fend;
  618. X    dialogdata.current = fend;
  619. X    dialogdata.yes = copyok;
  620. X    dialogdata.no = NULL;
  621. X    dialogdata.cancel = copycancel;
  622. X
  623. X    if (fstart == fend) {
  624. X       sprintf(label, "copy selected file to?");
  625. X       sprintf(defvalue, "%s", files[fstart]->d_name);
  626. X    }
  627. X    else {
  628. X       sprintf(label, "copy selected files to directory?");
  629. X       defvalue[0] = '\0';
  630. X    }
  631. X    create_prompt(&dialogdata, label, defvalue);
  632. X    return;
  633. X}
  634. X
  635. X
  636. X/***************************
  637. X*     Move Routines 
  638. X****************************/
  639. X
  640. X/* ARGSUSED */
  641. Xmoveok(clientdata)
  642. XDialogData *clientdata;
  643. X{
  644. X    int fstart = clientdata->start;
  645. X    int fend = clientdata->end;
  646. X    int i;
  647. X    char *s = clientdata->answer;
  648. X    char *name;
  649. X
  650. X    strcpy(cmdline, "mv ");
  651. X    for (i = fstart; i <= fend; i++) {
  652. X       strcat(cmdline, "'");
  653. X       strcat(cmdline, files[i]->d_name);
  654. X       strcat(cmdline, "' ");
  655. X    }
  656. X    if (*s == '~') {
  657. X       if ( (name = expand_tilde(s)) == NULL) {
  658. X           disp_message("\nMove: cannot expand target name");
  659. X           return;
  660. X       }
  661. X    }
  662. X    else name = s;
  663. X    strcat(cmdline, name);
  664. X
  665. X    if (execute_cmdline(cmdline, FALSE, TRUE) == 0) {
  666. X       DoList(clientdata->w, (caddr_t)clientdata, (caddr_t)0);
  667. X    }
  668. X    return;
  669. X}
  670. X
  671. Xmovecancel(clientdata)
  672. XDialogData *clientdata;
  673. X{
  674. X    return;
  675. X}
  676. X
  677. X/* ARGSUSED */
  678. XDoRename(w, client_data, call_data)
  679. XWidget w;
  680. Xcaddr_t client_data, call_data;
  681. X{
  682. X    XtTextPosition pos1, pos2, fstart, fend;
  683. X    char label[32];
  684. X    char defvalue[255];
  685. X
  686. X    if (check_prompt() == -1) return;
  687. X                /* there is already a prompt window */
  688. X    if (numfiles == 0) {
  689. X       disp_message("\nMove: no files listed");
  690. X       return;
  691. X    }
  692. X
  693. X    XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  694. X    if (pos1 == pos2 || select_files(pos1, pos2, &fstart, &fend) == -1) {
  695. X       disp_message("\nMove: no file selected");
  696. X       return;
  697. X    }
  698. X
  699. X    dialogdata.w = w;
  700. X    dialogdata.start = fstart;
  701. X    dialogdata.end = fend;
  702. X    dialogdata.current = fend;
  703. X    dialogdata.yes = moveok;
  704. X    dialogdata.no = NULL;
  705. X    dialogdata.cancel = movecancel;
  706. X
  707. X    if (fstart == fend) {
  708. X       sprintf(label, "move selected file to?");
  709. X       sprintf(defvalue, "%s", files[fstart]->d_name);
  710. X    }
  711. X    else {
  712. X       sprintf(label, "move selected files to directory?");
  713. X       defvalue[0] = '\0';
  714. X    }
  715. X
  716. X    create_prompt(&dialogdata, label, defvalue);
  717. X    return;
  718. X}
  719. X
  720. X
  721. X/***************************
  722. X*     Delete Routines 
  723. X****************************/
  724. X
  725. X/* ARGSUSED */
  726. Xupdate_list(fstart, fend, sort)
  727. Xint fstart, fend;
  728. Xshort sort;
  729. X{
  730. X    int i;
  731. X    int next = fstart;
  732. X    int position = files[fstart]->d_pos1;
  733. X
  734. X    for (i = fstart; i <= fend; i++) {
  735. X       if (files[i]->d_marked == 0) {
  736. X           if (next < i) files[next] = files[i];
  737. X           next++;
  738. X       }
  739. X       else if (! access(files[i]->d_name, F_OK) ) {
  740. X        disp_message("\nfile %s not removed", files[i]->d_name);
  741. X        if (next < i) files[next] = files[i];
  742. X           next++;
  743. X       }
  744. X       else XtFree(files[i]);
  745. X    }
  746. X    
  747. X    if (next == i) return; /* no files were deleted */
  748. X
  749. X    for (i = fend + 1; i < numfiles; i++) 
  750. X       files[next++] = files[i];
  751. X    numfiles = next;
  752. X    if (sort) ;/* then sort files again */
  753. X    display_files(position);
  754. X}
  755. X
  756. X/* ARGSUSED */
  757. Xconfirm(data, cur, op)
  758. XDialogData *data;
  759. Xint cur;
  760. Xrequesttype op;
  761. X{
  762. X    struct stat buf;
  763. X    char label[255];
  764. X
  765. X    data->current = cur;
  766. X    switch (op) {
  767. X    case DELETE:
  768. X        if (files[cur]->d_type == 'd')
  769. X            sprintf(label, "delete directory %s and its content?",
  770. X                   files[cur]->d_name);
  771. X        else if (files[cur]->d_type == 'l') {
  772. X           if (stat(files[cur]->d_name, &buf) == -1) {
  773. X            sprintf(label, 
  774. X                "cannot check status of %s; delete anyway?",
  775. X                   files[cur]->d_name);
  776. X           }
  777. X        }
  778. X        else     sprintf(label, "delete file %s",
  779. X                   files[cur]->d_name);
  780. X        break;
  781. X
  782. X    default: return;
  783. X    }
  784. X    create_confirm(data, label);
  785. X}
  786. X
  787. X
  788. X/* ARGSUSED */
  789. Xdeleteyes(clientdata)
  790. XDialogData *clientdata;
  791. X{
  792. X    int cur = clientdata->current;
  793. X    struct afile *fp;
  794. X
  795. X    fp = files[cur];
  796. X    if ( (strlen(cmdline) + strlen(fp->d_name) + 1) >= cmdsize) {
  797. X       cmdsize += 1024;
  798. X       XtRealloc(cmdsize, cmdsize);
  799. X    }
  800. X    strcat(cmdline, " '");
  801. X    strcat(cmdline, fp->d_name);
  802. X    strcat(cmdline, "'");
  803. X    fp->d_marked = 1;    /* file is marked for deletion */
  804. X
  805. X    if (cur < clientdata->end) {
  806. X       confirm(clientdata, cur+1, DELETE);
  807. X    }
  808. X    else {
  809. X       if (execute_cmdline(cmdline, FALSE, TRUE) == 0)
  810. X           update_list(clientdata->start, clientdata->end, 0);
  811. X    }
  812. X    return;
  813. X}
  814. X
  815. X/* ARGSUSED */
  816. Xdeleteno(clientdata)
  817. XDialogData *clientdata;
  818. X{
  819. X    int cur = clientdata->current;
  820. X    short found = 0;
  821. X    int i;
  822. X
  823. X    if (cur < clientdata->end) {
  824. X       confirm(clientdata, cur+1, DELETE);
  825. X    }
  826. X    else {
  827. X        /* check if there is any file to delete */
  828. X       for (i = clientdata->start; i <= clientdata->end; i++) {
  829. X           if (files[i]->d_marked != 0) {
  830. X              found = 1;
  831. X              break;
  832. X        }
  833. X       }
  834. X       if (!found) return;
  835. X       if (execute_cmdline(cmdline, FALSE, TRUE) == 0)
  836. X           update_list(clientdata->start, clientdata->end, 0);
  837. X    }
  838. X
  839. X    return;
  840. X}
  841. X
  842. X/* ARGSUSED */
  843. Xdeletecancel(clientdata)
  844. XDialogData *clientdata;
  845. X{
  846. X    int i;
  847. X
  848. X    for (i = clientdata->start; i <= clientdata->end; i++) 
  849. X       files[i]->d_marked = 0;
  850. X    return;
  851. X}
  852. X
  853. X
  854. X/* ARGSUSED */
  855. XDoDelete(w, client_data, call_data)
  856. XWidget w;
  857. Xcaddr_t client_data, call_data;
  858. X{
  859. X    XtTextPosition pos1, pos2, fstart, fend;
  860. X
  861. X    if (check_confirm() == -1) return;
  862. X                /* there is already a prompt window */
  863. X    if (numfiles == 0) {
  864. X       disp_message("\nDelete: no files listed");
  865. X       return;
  866. X    }
  867. X
  868. X    XtTextGetSelectionPos(listwidget, &pos1, &pos2);
  869. X    if (pos1 == pos2 || select_files(pos1, pos2, &fstart, &fend) == -1) {
  870. X       disp_message("\nDelete: no file selected");
  871. X       return;
  872. X    }
  873. X
  874. X    dialogdata.w = w;
  875. X    dialogdata.yes = deleteyes;
  876. X    dialogdata.no = deleteno;
  877. X    dialogdata.cancel = deletecancel;
  878. X    dialogdata.start = fstart;
  879. X    dialogdata.end = fend;
  880. X    strcpy(cmdline, "rm -rf");
  881. X
  882. X    confirm(&dialogdata, fstart, DELETE);
  883. X    return;
  884. X}
  885. X
  886. X
  887. X/*******************************
  888. X*     Parent Directory Routines 
  889. X********************************/
  890. X
  891. XDoParent(w, client_data, call_data)
  892. XWidget w;
  893. Xcaddr_t client_data, call_data;
  894. X{
  895. X    char *p;
  896. X
  897. X    if ( (int)call_data == 3) return;
  898. X            /* right button was pressed; no action is
  899. X            taken */
  900. X
  901. X    if ( (p = rindex(curdirectory, '/')) == NULL)
  902. X       disp_message("\nParent: cannot select parent directory");
  903. X    else {
  904. X       if ( (p - curdirectory) == 0) p[1] = '\0'; 
  905. X            /* already at the beginning */
  906. X       else p[0] = '\0';
  907. X       if (!(chdir(curdirectory))) 
  908. X        setup_dirlabel(curdirectory, filepattern);
  909. X       else disp_message("\nParent: problems in changing to %s",
  910. X            curdirectory);
  911. X    }
  912. X
  913. X    XtTextUnsetSelection(listwidget);
  914. X
  915. X    switch ((int)call_data) {
  916. X       case 2: 
  917. X        clear_widget(listwidget, listsource); break;
  918. X
  919. X       case 1: 
  920. X       default: 
  921. X        XtTextUnsetSelection(listwidget);
  922. X        DoList(w, client_data, (caddr_t)0); break;
  923. X    }
  924. X
  925. X    return;
  926. X}
  927. END_OF_FILE
  928. if test 18919 -ne `wc -c <'commands.c'`; then
  929.     echo shar: \"'commands.c'\" unpacked with wrong size!
  930. fi
  931. # end of 'commands.c'
  932. fi
  933. if test -f 'search.c' -a "${1}" != "-c" ; then 
  934.   echo shar: Will not clobber existing file \"'search.c'\"
  935. else
  936. echo shar: Extracting \"'search.c'\" \(12704 characters\)
  937. sed "s/^X//" >'search.c' <<'END_OF_FILE'
  938. X/* Systems Sciences Laboratory, Webster Research Center */
  939. X
  940. Xstatic char *PROGRAM_information[] =
  941. X{
  942. X    "Copyright (c) 1988 Xerox Corporation.  All rights reserved.",
  943. X    "$Header$",
  944. X    "$Locker$"
  945. X}
  946. X;
  947. X
  948. X/*
  949. X * Copyright protection claimed includes all forms and matters of copyrightable
  950. X * material and information now allowed by statutory or judicial lay or
  951. X * herinafter granted, including without limitation, material generated from
  952. X * the software programs which are displayed on the screen such as icons,
  953. X * screen display looks, etc.
  954. X */
  955. Xstatic int errornum;
  956. Xstatic int hitfilesize;
  957. X
  958. X#define MAXDISPLAY 256
  959. X#define BLKSIZE 8192
  960. X#define ESIZE 1024
  961. X
  962. X#define INIT   register char *sp = instring;
  963. X#define GETC() (*sp++)
  964. X#define PEEKC()     (*sp)
  965. X#define UNGETC(c)   (--sp)
  966. X#define RETURN(c)   return;
  967. X#define ERROR(c)    { errornum = c; return; }
  968. X
  969. X#include <regexp.h>
  970. X#include <sys/file.h>
  971. X#include <ctype.h>
  972. X#include "xfilebrowser.h"
  973. X
  974. X
  975. Xstatic short recursion = 1;
  976. X        /* 1 no recursive search of directories
  977. X           2 search one level of directories
  978. X           3 search all levels of directories */
  979. X
  980. Xstatic Widget searchshell = NULL;
  981. Xstatic Widget searchoption;    /* option for sorting files */
  982. Xstatic Widget optioncaller;
  983. Xstatic Widget caseoption;    /* togglewidget selecting case sensitive */
  984. X
  985. Xstatic short disp_option = 0;
  986. X
  987. Xstatic Boolean filefound = False;
  988. Xstatic char *searchbuf;
  989. Xstatic int blksize;
  990. Xstatic Boolean recursive = False;
  991. Xstatic XtState ignore_case = XtToggleOff;    /* is grep case insensitive */
  992. X
  993. X
  994. Xextern char *re_comp();
  995. X
  996. X
  997. X
  998. X
  999. X/*************************************
  1000. X**    build options dialog for search
  1001. X**************************************/
  1002. X
  1003. Xcheck_search()
  1004. X{
  1005. X    return disp_option;
  1006. X}
  1007. X
  1008. Xstatic void DoApply()
  1009. X{
  1010. X    recursion = XtOptionGetSelection(searchoption);
  1011. X
  1012. X    ignore_case = GetToggle(caseoption);
  1013. X
  1014. X    disp_option = 0;
  1015. X    change_sensitive(optioncaller, TRUE);
  1016. X    XtPopdown(searchshell);
  1017. X}
  1018. X
  1019. Xstatic void DoCancel()
  1020. X{
  1021. X    XtState toggle;
  1022. X
  1023. X    /* reset the option dialog window */
  1024. X    if ( !(recursion == XtOptionGetSelection(searchoption)) ) 
  1025. X        /* sorting was modified by user */
  1026. X       XtOptionSetSelection(searchoption, recursion);
  1027. X
  1028. X    SetToggle(caseoption, ignore_case);
  1029. X
  1030. X    disp_option = 0;
  1031. X    change_sensitive(optioncaller, TRUE);
  1032. X    XtPopdown(searchshell);
  1033. X}
  1034. X
  1035. Xbuild_searchoptions()
  1036. X{
  1037. X    Arg popargs[1];
  1038. X    Widget listpane, listrow1, listrow2;
  1039. X
  1040. X    static Arg paneargs[] = {
  1041. X       { XtNallowResize, (XtArgVal)True },
  1042. X    };
  1043. X
  1044. X    static Arg toggleargs[] = {
  1045. X       { XtNstate, (XtArgVal)XtToggleOff },
  1046. X    };
  1047. X    
  1048. X    static Arg optionargs[] = { 
  1049. X       { XtNlabel, (XtArgVal)NULL },
  1050. X       { XtNorientation,(XtArgVal)XtorientVertical },
  1051. X       { XtNfromHoriz, (XtArgVal) NULL },
  1052. X       { XtNfromVert, (XtArgVal) NULL },
  1053. X       { XtNleft, (XtArgVal) XtChainLeft },
  1054. X       { XtNright, (XtArgVal) XtChainLeft },
  1055. X       { XtNtop, (XtArgVal) XtChainTop },
  1056. X       { XtNbottom, (XtArgVal) XtChainTop }
  1057. X
  1058. X    };
  1059. X
  1060. X    XtSetArg( popargs[0], XtNborderWidth, 2 );
  1061. X    
  1062. X    searchshell = XtCreatePopupShell("searchshell",
  1063. X               overrideShellWidgetClass,
  1064. X            toplevel, popargs, XtNumber(popargs));
  1065. X
  1066. X    listpane = XtCreateManagedWidget( "vpaned", vPanedWidgetClass, 
  1067. X            searchshell, paneargs , XtNumber(paneargs) );
  1068. X    listrow1 = XtCreateManagedWidget("row1", boxWidgetClass, 
  1069. X            listpane, NULL,0);
  1070. X    listrow2 = XtCreateManagedWidget("row2", boxWidgetClass, 
  1071. X            listpane, NULL,0);
  1072. X    makeCommandButton(listrow1, "Apply", DoApply);
  1073. X    makeCommandButton(listrow1, "Cancel", DoCancel);
  1074. X
  1075. X        /* define option menu for searching directories */
  1076. X    optionargs[0].value = (XtArgVal)"Select Search Option:";
  1077. X    searchoption = XtCreateManagedWidget("searching", optionWidgetClass, 
  1078. X        listrow2, optionargs, XtNumber(optionargs));
  1079. X    XtOptionAddOption(searchoption, "skip directories", TRUE);
  1080. X    XtOptionAddOption(searchoption, "search next-level directory", FALSE);
  1081. X    XtOptionAddOption(searchoption, "search all directories", FALSE);
  1082. X
  1083. X        /* define toggle for selecting case sensitivity */
  1084. X    caseoption = XtCreateManagedWidget("case insensitive search",
  1085. X        toggleWidgetClass,
  1086. X        listrow2, toggleargs, XtNumber(toggleargs));
  1087. X
  1088. X    XtSetMappedWhenManaged(searchshell, FALSE);
  1089. X    XtRealizeWidget(searchshell);
  1090. X}
  1091. X
  1092. X
  1093. Xdisplay_searchoptions(caller)
  1094. XWidget caller;
  1095. X{
  1096. X    if (searchshell == NULL) {
  1097. X       build_searchoptions();
  1098. X       optioncaller = caller;
  1099. X    }
  1100. X
  1101. X    disp_option = 1;
  1102. X    move_popup(searchshell, caller);
  1103. X    change_sensitive(caller, FALSE);
  1104. X    XtMapWidget(searchshell);
  1105. X    XtPopup(searchshell, XtGrabNonexclusive);
  1106. X}
  1107. X
  1108. X/**********************************************
  1109. X**    build data file structure for grep files
  1110. X***********************************************/
  1111. X
  1112. Xfree_hitfiles()
  1113. X{
  1114. X    register int i;
  1115. X    register LineElement *p, *tmp;
  1116. X
  1117. X    if (hitfiles != (SearchElement **)NULL) {
  1118. X       for (i = 0; i < numhitfiles; i++) {
  1119. X        p = hitfiles[i]->lines;
  1120. X        while (p != (LineElement *)NULL) {
  1121. X           tmp = p->next;
  1122. X           XtFree(p);
  1123. X           p = tmp;
  1124. X        }
  1125. X        XtFree(hitfiles[i]);
  1126. X       }
  1127. X       numhitfiles = 0;
  1128. X    }
  1129. X}
  1130. X
  1131. XLineElement *add_line(pos1, pos2, line, next)
  1132. XXtTextPosition pos1, pos2;
  1133. Xint line;
  1134. XLineElement *next;
  1135. X{
  1136. X    register LineElement *p;
  1137. X
  1138. X    p = (LineElement *)XtMalloc(sizeof(LineElement));
  1139. X    p->pa = pos1;
  1140. X    p->pe = pos2;
  1141. X    p->linenumber = line;
  1142. X    p->next = next;
  1143. X    return p;    
  1144. X}
  1145. X
  1146. Xadd_file(fname, pos1, pos2, linenr)
  1147. Xchar *fname;
  1148. XXtTextPosition pos1, pos2;
  1149. Xint linenr;
  1150. X{
  1151. X    SearchElement *selem;
  1152. X    if (numhitfiles == hitfilesize) {
  1153. X       hitfilesize += (numfiles > 64) ? (2 * numfiles): 128;
  1154. X       if (hitfiles != (SearchElement **)NULL)
  1155. X           hitfiles = (SearchElement **)XtRealloc(hitfiles, 
  1156. X               hitfilesize * sizeof(SearchElement *));
  1157. X       else 
  1158. X        hitfiles = 
  1159. X        (SearchElement **)XtMalloc(hitfilesize*sizeof(SearchElement *));
  1160. X    }
  1161. X
  1162. X    if ( numhitfiles <= 0 || 
  1163. X            strcmp(fname, hitfiles[numhitfiles-1]->name) ) {
  1164. X       selem = (SearchElement *)XtMalloc(sizeof(SearchElement));
  1165. X       selem->pos1 = pos1;
  1166. X       selem->pos2 = pos2;
  1167. X       selem->lines = add_line(pos1, pos2, linenr, (LineElement *)NULL);
  1168. X       strcpy(selem->name, fname);
  1169. X       hitfiles[numhitfiles] = (SearchElement *)selem;
  1170. X
  1171. X       numhitfiles++;
  1172. X    }
  1173. X    else {
  1174. X       hitfiles[numhitfiles-1]->lines = 
  1175. X           add_line(pos1, pos2, linenr, hitfiles[numhitfiles-1]->lines);
  1176. X       hitfiles[numhitfiles-1]->pos2 = pos2;
  1177. X    }
  1178. X}
  1179. X
  1180. Xdisp_searchline(file, line, linenr)
  1181. Xchar *file, *line;
  1182. Xint linenr;
  1183. X{
  1184. X    XtTextBlock text;
  1185. X    XtTextPosition pos;
  1186. X
  1187. X    text.length = strlen(line);
  1188. X    text.ptr = line;
  1189. X    text.firstPos = 0;
  1190. X    allowedit = 1;
  1191. X
  1192. X    pos = (*grepsource->Scan)(grepsource, 0, XtstAll, XtsdRight, 1, 0);
  1193. X
  1194. X    XtTextReplace(grepwidget, pos, pos, &text);
  1195. X    allowedit = 0;
  1196. X    add_file(file, pos, (pos + text.length + 1), linenr);
  1197. X}
  1198. X
  1199. Xdet_surround(file, start, end, linenr)
  1200. Xchar *file, *start, *end;
  1201. Xint linenr;
  1202. X{
  1203. X    int i, len;
  1204. X    char tmpline[MAXDISPLAY + 1];
  1205. X
  1206. X    sprintf(tmpline, "%s: ", file);
  1207. X    len = MAXDISPLAY - strlen(tmpline) - 2;
  1208. X    if ( (end - start) < len ) 
  1209. X       strcat(tmpline, start);
  1210. X    else if ( (i = loc2 - start) < len) {
  1211. X       strncat(tmpline, start, i);
  1212. X       tmpline[i] = '\0';
  1213. X    }
  1214. X    else {
  1215. X       strncat(tmpline, loc1, len);
  1216. X       tmpline[MAXDISPLAY - 2] = '\0';
  1217. X    }
  1218. X    strcat(tmpline, "\n");
  1219. X    disp_searchline(file, tmpline, linenr);
  1220. X    filefound = True;
  1221. X}
  1222. X
  1223. Xint check_textfile(p)
  1224. Xchar *p;
  1225. X{
  1226. X    switch (*(int *)p) {
  1227. X    case 0177555:
  1228. X    case 0177545:
  1229. X    case 070707:    return(-1);
  1230. X    }
  1231. X    switch (*(short *)(p+2)) {
  1232. X    case 0407: 
  1233. X    case 0413:    return(-1);
  1234. X    }
  1235. X
  1236. X    if (strncmp(p, "Interpress", 10) == 0) return(-1);
  1237. X    else if (strncmp(p, "\037\036", 2) == 0) return(-1);
  1238. X    else if (strncmp(p, "\377\037", 2) == 0) return(-1);
  1239. X    else if (strncmp(p, "\037\235", 2) == 0) return(-1);
  1240. X    return(0);
  1241. X}
  1242. X
  1243. Xint search_file(filelist, index, expbuf, stop)
  1244. Xstruct afile **filelist;
  1245. Xint index;
  1246. Xchar *expbuf;
  1247. XBoolean stop;
  1248. X{
  1249. X    int fp, first = 1;
  1250. X    int count = 0, i, j;
  1251. X    int linenr = 0;
  1252. X    char *p;
  1253. X    char *q, *h;
  1254. X    char *linebuf;
  1255. X    struct stat statbuf;
  1256. X
  1257. X    char *filename = filelist[index]->d_name;
  1258. X
  1259. X        /* check file type */
  1260. X    switch (filelist[index]->d_type) {
  1261. X    case 'b':
  1262. X    case 'c':
  1263. X    case 's':    return(-1);
  1264. X    case 'd':    /* handle directories */
  1265. X       {
  1266. X        struct afile **dirfiles;
  1267. X        int numdirfiles, i;
  1268. X        
  1269. X        if ( (recursion == 1) ||
  1270. X            (recursion == 2 && recursive) ) return(-1);
  1271. X        recursive = True;
  1272. X        setup_filepattern("*");
  1273. X        if (prepare_list(filename, 0, &dirfiles, &numdirfiles,
  1274. X                filename))
  1275. X           return(-1);
  1276. X        setup_filepattern(filepattern);
  1277. X
  1278. X        for (i = 0; (i < numdirfiles && (!stop || !filefound) ); i++)
  1279. X           search_file(dirfiles, i, expbuf, stop);
  1280. X        free_direct(&dirfiles, &numdirfiles);
  1281. X        recursive = False;
  1282. X        return(0);
  1283. X       }
  1284. X    default:    break;
  1285. X    }
  1286. X        /* check if file pattern matches */
  1287. X    if (! re_exec(filename)) return(-1);    
  1288. X    if ( (fp = open(filename, O_RDONLY)) < 0) {
  1289. X       disp_message("\nSearch: cannot open file %s", filename);
  1290. X       return(-1);
  1291. X    }
  1292. X    if (fstat(fp, &statbuf) == -1) { close(fp); return(-1); }
  1293. X    else if ( !(statbuf.st_mode & S_IFREG )) {
  1294. X       disp_message("\nSearch: %s not regular file!", filename);
  1295. X       close(fp);
  1296. X       return(-1);
  1297. X    }
  1298. X
  1299. X    if (searchbuf == NULL) {
  1300. X       if (statbuf.st_blksize > 0)
  1301. X        blksize = statbuf.st_blksize;
  1302. X       else    blksize = BLKSIZE;
  1303. X       searchbuf = (char *)XtMalloc(blksize+ (2*MAXDISPLAY));
  1304. X    }
  1305. X    p = searchbuf;
  1306. X    while ( (i = read(fp, p, blksize)) > 0) {
  1307. X              if (first) {
  1308. X           /* check if file can be scanned */
  1309. X        if (check_textfile(p) == -1) {
  1310. X           disp_message("\nSearch: %s does not contain text!",
  1311. X             filename);
  1312. X           close(fp);
  1313. X              return(-1);
  1314. X        }
  1315. X        first = 0;
  1316. X       }
  1317. X
  1318. X       if (count == 0) {
  1319. X        while (*p == '\n') { i--; p++; linenr++; }
  1320. X        if (i == 0) continue; else count = i;
  1321. X       }
  1322. X       else count += i;
  1323. XNEXT:
  1324. X       linebuf = p;  p++;  j = 1;
  1325. X       while ( (j < min(MAXDISPLAY, count)) && *p != '\n' )
  1326. X        { p++; j++; }
  1327. X       if ( j < MAXDISPLAY && *p != '\n' ) {
  1328. X        q = searchbuf; h = linebuf; j = 1;
  1329. X        while (j++ <= count) *q++ = *h++;
  1330. X        linebuf = searchbuf;
  1331. X        p = linebuf + count;
  1332. X        continue;
  1333. X       }
  1334. X
  1335. X       if (*p == '\n') linenr++;
  1336. X       *p = '\0'; 
  1337. X       if (step(linebuf, expbuf)) 
  1338. X        det_surround(filename, linebuf, p, linenr);
  1339. X       count -= j + 1;
  1340. X       if (count == 0) { p = searchbuf; continue; }
  1341. X       else {
  1342. X        p++;
  1343. X           while (*p == '\n' && count > 0) { p++; count--; linenr++; }
  1344. X       }
  1345. X       if (count > 0) goto NEXT; else { p = searchbuf; continue; }
  1346. X    }
  1347. X
  1348. X    if (count > 0) {
  1349. X        *(p+1) = '\0';
  1350. X        if (step(linebuf, expbuf)) 
  1351. X        det_surround(filename, linebuf, p, linenr);
  1352. X    }
  1353. X    close(fp);
  1354. X    return(0);
  1355. X}
  1356. X
  1357. Xint examine_files(fstart, fend, stop)
  1358. Xint fstart, fend;
  1359. XBoolean stop;
  1360. X{
  1361. X    int i;
  1362. X    char expbuf[ESIZE+1];
  1363. X    char *greppattern;
  1364. X    char *setup_search();
  1365. X
  1366. X    greppattern = setup_search(searchpattern);
  1367. X    errornum = 0;
  1368. X    compile(greppattern, expbuf, &expbuf[ESIZE], '\0');
  1369. X    XtFree(greppattern);
  1370. X    if (errornum != 0) {
  1371. X       switch (errornum) {
  1372. X       case 50: 
  1373. X        disp_message("\nSearch: Regular expression overflow");
  1374. X        break;
  1375. X       case 49:
  1376. X        disp_message("\nSearch: [ ] imbalance");
  1377. X        break;
  1378. X       case 46:
  1379. X        disp_message("\nSearch: First number exceeds second in \\{ \\}");
  1380. X        break;
  1381. X       case 45:
  1382. X        disp_message("\nSearch: } expected after \\");
  1383. X        break;
  1384. X       case 44:
  1385. X        disp_message("\nSearch: More than 2 numbers given in \\{ \\}");
  1386. X        break;
  1387. X       case 43:
  1388. X        disp_message("\nSearch: Too many \\(");
  1389. X        break;
  1390. X       case 42:
  1391. X        disp_message("\nSearch: \\( \\) imbalance");
  1392. X        break;
  1393. X       case 36:
  1394. X        disp_message("\nSearch: Illegal or missing delimiter");
  1395. X        break;
  1396. X
  1397. X       default:
  1398. X        disp_message("\nSearch: search pattern failure %d", errornum);
  1399. X       }
  1400. X       return(-1);
  1401. X    }
  1402. X
  1403. X    setup_filepattern(filepattern);
  1404. X    filefound = False;
  1405. X    for (i = fstart; (i <= fend && (!stop || !filefound) ); i++)
  1406. X       search_file(files, i, expbuf, stop);
  1407. X    return(0);
  1408. X}
  1409. X
  1410. X/**********************************************
  1411. X**    search utility routines
  1412. X***********************************************/
  1413. X
  1414. Xint setup_filepattern(pattern)
  1415. Xchar *pattern;
  1416. X{
  1417. X    char tmppattern[64];
  1418. X    char *error;
  1419. X
  1420. X    setup_pattern(pattern, tmppattern);
  1421. X    if (error = re_comp(tmppattern)) {
  1422. X       disp_message("\nsearch pattern for files %s?", error);
  1423. X       return(-1);
  1424. X    }
  1425. X    return(0);
  1426. X}
  1427. X
  1428. Xchar *setup_search(s)
  1429. Xchar *s;
  1430. X{
  1431. X    char *target, *src = s, *dest;
  1432. X    char c;
  1433. X
  1434. X    if (ignore_case == XtToggleOff) {
  1435. X       target = XtMalloc(strlen(s) + 1);
  1436. X       strcpy(target, s);
  1437. X    }
  1438. X    else {
  1439. X        /* allocate maximum memory */
  1440. X       target = XtMalloc(4 * strlen(s) + 1);
  1441. X       dest = target;
  1442. X
  1443. X       while (c = *src++) {
  1444. X           if (isalpha(c)) {
  1445. X              *dest++ = '[';
  1446. X              *dest++ = c;
  1447. X              *dest++ = ',';
  1448. X
  1449. X              if (islower(c))     *dest++ = toupper(c); 
  1450. X           else         *dest++ = tolower(c); 
  1451. X
  1452. X           *dest++ = ']';
  1453. X           }
  1454. X           else *dest++ = c;
  1455. X       }
  1456. X       *dest = '\0';
  1457. X    }
  1458. X    return(target);
  1459. X}
  1460. X
  1461. Xint select_searchfile(start, end, line)
  1462. Xint start, end;
  1463. Xint *line;
  1464. X{
  1465. X    int i = 0;
  1466. X    register LineElement *p;
  1467. X
  1468. X    while (i < numhitfiles && hitfiles[i]->pos1 <= start) i++; 
  1469. X    if ( (hitfiles[i-1]->pos2 + 1) < end) { *line = 0; return(-1); }
  1470. X    else {
  1471. X       p = hitfiles[i-1]->lines;
  1472. X       while (p != (LineElement *)NULL && (p->pa > start) ) p = p->next;
  1473. X
  1474. X       if (p == (LineElement *)NULL) 
  1475. X           *line = 0; 
  1476. X       else *line = p->linenumber;
  1477. X
  1478. X       return(i-1);
  1479. X    }
  1480. X}
  1481. END_OF_FILE
  1482. if test 12704 -ne `wc -c <'search.c'`; then
  1483.     echo shar: \"'search.c'\" unpacked with wrong size!
  1484. fi
  1485. # end of 'search.c'
  1486. fi
  1487. if test -f 'util.c' -a "${1}" != "-c" ; then 
  1488.   echo shar: Will not clobber existing file \"'util.c'\"
  1489. else
  1490. echo shar: Extracting \"'util.c'\" \(4542 characters\)
  1491. sed "s/^X//" >'util.c' <<'END_OF_FILE'
  1492. X/* Systems Sciences Laboratory, Webster Research Center */
  1493. X
  1494. Xstatic char *PROGRAM_information[] =
  1495. X{
  1496. X    "Copyright (c) 1988 Xerox Corporation.  All rights reserved.",
  1497. X    "$Header$",
  1498. X    "$Locker$"
  1499. X}
  1500. X;
  1501. X
  1502. X/*
  1503. X * Copyright protection claimed includes all forms and matters of copyrightable
  1504. X * material and information now allowed by statutory or judicial lay or
  1505. X * herinafter granted, including without limitation, material generated from
  1506. X * the software programs which are displayed on the screen such as icons,
  1507. X * screen display looks, etc.
  1508. X */
  1509. X
  1510. X
  1511. X#include "xfilebrowser.h"
  1512. X#include <ctype.h>
  1513. X
  1514. Xextern char *get_userdir();
  1515. X
  1516. X/* ARGSUSED */
  1517. Xdisp_message(fmt, arg1, arg2, arg3, arg4)
  1518. X  char *fmt;
  1519. X{
  1520. X    char buf[1024];
  1521. X    int maxlength = 1024;
  1522. X    XtTextBlock text;
  1523. X    XtTextPosition pos, start;
  1524. X
  1525. X    sprintf(buf, fmt, arg1, arg2, arg3, arg4);
  1526. X    text.length = strlen(buf);
  1527. X    text.ptr = buf;
  1528. X    text.firstPos = 0;
  1529. X    allowedit = 1;
  1530. X
  1531. X    pos = (*messsource->Scan)(messsource, 0, XtstAll, XtsdRight,1,0);
  1532. X
  1533. X    if ( (pos + text.length) > maxlength)  start = 0;
  1534. X    else start = pos;
  1535. X    XtTextReplace( messwidget, start, pos, &text);
  1536. X    XtTextSetInsertionPoint(messwidget, start + text.length);
  1537. X
  1538. X    allowedit = 0;
  1539. X    /* Feep(); */
  1540. X}
  1541. X
  1542. X
  1543. X/* ARGSUSED */
  1544. XWidget makeCommandButton(box, name, function)
  1545. X  Window box;
  1546. X  char *name;
  1547. X  XtCallbackProc function;
  1548. X{
  1549. X  static XtCallbackRec callbackList[] = { {NULL, NULL}, {NULL, NULL} };
  1550. X  static Arg arg[] = { {XtNcallback,(XtArgVal)callbackList} };
  1551. X
  1552. X    callbackList[0].callback = function;
  1553. X    return (XtCreateManagedWidget(name, commandWidgetClass, box, arg, 1));
  1554. X}
  1555. X
  1556. X/* ARGSUSED */
  1557. XWidget makeStringBox(parentBox, string, length)
  1558. X  Widget parentBox;
  1559. X  char *string;
  1560. X{
  1561. X  Arg args[5];
  1562. X  Widget StringW;
  1563. X  int numargs;
  1564. X    numargs = 0;
  1565. X    MakeArg(XtNeditType, (XtArgVal)XttextEdit );
  1566. X    MakeArg(XtNtextOptions, (XtArgVal)( resizeWidth)); 
  1567. X    MakeArg(XtNstring,(XtArgVal)string);     
  1568. X    MakeArg(XtNwidth,  (XtArgVal)length);
  1569. X    MakeArg(XtNlength, (XtArgVal)1000);
  1570. X    StringW = XtCreateManagedWidget("stringthing", asciiStringWidgetClass, 
  1571. X                    parentBox, args, numargs);
  1572. X    return(StringW);  
  1573. X}
  1574. X
  1575. X/* ARGSUSED */
  1576. Xclear_widget(w, wsrc)
  1577. XWidget w;
  1578. XXtTextSource wsrc;
  1579. X{
  1580. X    XtTextBlock text;
  1581. X    XtTextPosition end;
  1582. X    
  1583. X    allowedit = 1;
  1584. X    text.length = 0;
  1585. X    text.ptr = "";
  1586. X    text.firstPos = 0;
  1587. X
  1588. X    end = (*wsrc->Scan)(wsrc, 0, XtstAll, XtsdRight, 1, 0);
  1589. X
  1590. X    XtTextReplace(w, 0, end, &text);
  1591. X    XtTextUnsetSelection(w);
  1592. X    XtTextSetInsertionPoint(w, 0);
  1593. X    allowedit = 0;
  1594. X}
  1595. X
  1596. X
  1597. Xint setup_dirlabel(dir, pattern)
  1598. Xchar *dir, *pattern;
  1599. X{
  1600. X    Arg dirargs[1];
  1601. X    XtTextSource src;
  1602. X    XtTextBlock text, block;
  1603. X    XtTextPosition end;
  1604. X
  1605. X        /* setup the new pattern in the fpatwindow widget */    
  1606. X    allowedit = 1;
  1607. X    text.length = strlen(pattern);
  1608. X    text.ptr = pattern;
  1609. X    text.firstPos = 0;
  1610. X
  1611. X    src = XtTextGetSource(fpatwindow);
  1612. X    (void)(*src->Read)(src, 0, &block, 254);
  1613. X
  1614. X    end = block.length;
  1615. X    XtTextReplace(fpatwindow, 0, end, &text);
  1616. X    allowedit = 0;
  1617. X
  1618. X        /* setup the new directory label in dirwidget */
  1619. X    XtSetArg(dirargs[0], XtNlabel, dir);
  1620. X    XtSetValues(dirwidget, dirargs, XtNumber(dirargs));
  1621. X}
  1622. X
  1623. X
  1624. Xsetup_iconname()
  1625. X{
  1626. X    Arg topargs[1];
  1627. X    char *p;
  1628. X    char pattern[32];
  1629. X
  1630. X    if ( ((p = rindex(curdirectory, '/')) == NULL) || (strlen(p) == 1))
  1631. X        XtSetArg(topargs[0], XtNiconName, (XtArgVal)"xbrowser");
  1632. X    else {
  1633. X       sprintf(pattern, "../%s", p+1);
  1634. X       XtSetArg(topargs[0], XtNiconName, (XtArgVal)pattern);
  1635. X    }
  1636. X    XtSetValues(toplevel, topargs, XtNumber(topargs));
  1637. X}
  1638. X
  1639. X/* ARGSUSED */
  1640. Xint getsize(w, width, height)
  1641. XWidget w;
  1642. XDimension *width, *height;
  1643. X{
  1644. X    static Dimension twidth, theight;
  1645. X    
  1646. X    static Arg args[] = {
  1647. X      {XtNwidth, (XtArgVal)&twidth},
  1648. X          {XtNheight, (XtArgVal)&theight},
  1649. X        };
  1650. X
  1651. X    XtGetValues(w, args, (Cardinal)2);
  1652. X    *width = twidth;
  1653. X    *height = theight;
  1654. X}
  1655. X
  1656. X/* ARGSUSED */
  1657. Xint getpos(w, posx, posy)
  1658. XWidget w;
  1659. XPosition *posx, *posy;
  1660. X{
  1661. X    static  Position tposx, tposy;
  1662. X    
  1663. X    static Arg args[] = { 
  1664. X       {XtNy, (XtArgVal)&tposy},
  1665. X           {XtNx, (XtArgVal)&tposx},
  1666. X        };
  1667. X
  1668. X    XtGetValues(w, args, (Cardinal)2);
  1669. X    *posx = tposx;
  1670. X    *posy = tposy;
  1671. X}
  1672. X
  1673. X/* ARGSUSED */
  1674. Xchar *expand_tilde(s)
  1675. Xchar *s;
  1676. X{
  1677. X    char *home, *getenv();
  1678. X    char *p, *fullname;
  1679. X    int i;
  1680. X    char user[12];
  1681. X
  1682. X    if (s[0] == '~' && (s[1] == '\0' || s[1] == '/') ) {
  1683. X       home = getenv("HOME");
  1684. X       p = s + 1;
  1685. X    }
  1686. X    else if (s[0] == '~' && isalnum(s[1])) {
  1687. X       p = s + 1;
  1688. X       i = 0;
  1689. X       while (*p != '/' && *p != '\0')   user[i++] = *p++; 
  1690. X       user[i] = '\0'; 
  1691. X
  1692. X       if ( (home = get_userdir(user)) == NULL) return((char *)NULL);
  1693. X    }
  1694. X
  1695. X    fullname = XtMalloc(strlen(home) + strlen(p));
  1696. X    sprintf(fullname, "%s%s", home, p);
  1697. X    return fullname;
  1698. X}
  1699. X
  1700. END_OF_FILE
  1701. if test 4542 -ne `wc -c <'util.c'`; then
  1702.     echo shar: \"'util.c'\" unpacked with wrong size!
  1703. fi
  1704. # end of 'util.c'
  1705. fi
  1706. if test -f 'xbrowser.man' -a "${1}" != "-c" ; then 
  1707.   echo shar: Will not clobber existing file \"'xbrowser.man'\"
  1708. else
  1709. echo shar: Extracting \"'xbrowser.man'\" \(13458 characters\)
  1710. sed "s/^X//" >'xbrowser.man' <<'END_OF_FILE'
  1711. X.TH XBROWSER 1 "25 October 1988" "X Version 11"
  1712. X.SH NAME
  1713. Xxbrowser - simple directory and file browser for X
  1714. X.SH SYNTAX
  1715. X\fBxbrowser\fP [ \fI-toolkitoption\fP ...] [ directory ]
  1716. X.SH OPTIONS
  1717. X.I Xbrowser
  1718. Xaccepts all of the standard X Toolkit command line options,
  1719. X(such as geometry, etc.) plus:
  1720. X.TP 8
  1721. X.I directory
  1722. XSpecifies the startup directory for subsequent searches within 
  1723. X.I xbrowser.
  1724. XIf no directory is specified, the current working directory is
  1725. Xchosen as the startup directory.
  1726. X.SH DESCRIPTION
  1727. X.I Xbrowser
  1728. Xprovides a graphical interface to browse directories, select files from
  1729. Xdirectory listings and invoke commands on them, such as invoking
  1730. Xthe editor on these files,
  1731. Xsearch files for specified patterns, move, copy or delete
  1732. Xfiles. The application provides
  1733. Xa window consisting of the following areas:
  1734. X.IP "Commands Menu" 8
  1735. XSpecifies commands for browsing directories and invoking the editor
  1736. Xon selected files (possible commands are \fBQuit\fP, \fBList\fP,
  1737. X\fBEdit\fP, \fBParent\fP, \fBShell\fP, \fBCopy\fP, \fBMove\fP,
  1738. X\fBDelete\fP).
  1739. X.IP "File Pattern Box"
  1740. XDefines the file name pattern for searching directories.
  1741. XIt accepts the same
  1742. Xnotation as 
  1743. X.I ls
  1744. X(except for environment variables which are currently not supported).
  1745. XThe characters *, $ and ~ are expanded as defined by C-Shell. 
  1746. XThe current working directory and
  1747. Xthe pattern defined by the File Pattern Box are combined to define the
  1748. Xsearch directory and the search pattern for files. For example,
  1749. X"net/src/*.c" searches in the directory "<current directory>/net/src"
  1750. Xfor all files whose name end with ".c". After each search the 
  1751. Xfile pattern box is updated: only the file pattern is displayed,
  1752. Xthe directory portion is extracted. The search directory becomes the
  1753. Xcurrent working directory of
  1754. X.I xbrowser.
  1755. X.IP "Directory Label"
  1756. XDisplays the current working directory of
  1757. X.I xbrowser.
  1758. XIf the file pattern does not specify an absolute path name, the current
  1759. Xdirectory is prepended to define the search directory.
  1760. X.IP "Message Window"
  1761. XDisplays
  1762. X.I xbrowser
  1763. Xmessages, such as error messages or messages returned by shell programs
  1764. Xwhich were invoked via the Shell command.
  1765. X.IP "File Window"
  1766. XDisplays a list of files which are members of the current directory used by
  1767. X.I xbrowser.
  1768. XThe files listed in this window depend on the pattern defined by the
  1769. XFile Pattern Box. Each line of the File Window displays the characteristics
  1770. Xof one file (the window does not use word wrap; the toolkit 
  1771. Xshould display a
  1772. Xhorizontal scrollbar for the text widget but the current version
  1773. Xdoes not implement it correctly).
  1774. X
  1775. XThe meaning of the characteristics is exactly the same as for the
  1776. X.I ls
  1777. Xcommand. 
  1778. X.I xbrowser
  1779. Xdisplays the file type, the access rights, the number of links, the
  1780. Xowner, the file size in bytes, the last modification date and the 
  1781. Xfile name. This window allows the user only to select one or
  1782. Xseveral lines; individual characters cannot be selected. 
  1783. X
  1784. XA single click
  1785. Xof the left mouse button selects one line. The selection of files
  1786. Xmay be extended by
  1787. Xusing the right mouse button. The selected files can be 
  1788. Xde-selected by hitting a character generating key (no modifier keys)
  1789. Xof the keyboard or by clicking the middle button of the mouse.
  1790. XA double click on a line is a shortcut for selecting a file and invoking
  1791. Xexplicitly the commands \fBList\fP or \fBView/Edit\fP. If the double-clicked
  1792. Xfile is a directory the \fBList\fP command is executed; otherwise the command
  1793. X\fBView/Edit\fP is executed (if the resource \fBViewEdit\fP is set to "true"
  1794. X.I xbrowser
  1795. Xinvokes the desired editor rather than 
  1796. X.I xmore). 
  1797. X.IP "Search Commands"
  1798. XLists the commands to search text files for specified patterns
  1799. X(possible commands are 
  1800. X\fBEdit\fP and  \fBGrep\fP).
  1801. X.IP "Grep Window"
  1802. XDisplays lines of text files which match the current search pattern. Each
  1803. Xline consists of the file name, followed by a colon and a space, followed
  1804. Xby the matching line (restricted to 256 characters).
  1805. XThis window allows the user only to select one or
  1806. Xseveral lines; individual characters cannot be selected.
  1807. X
  1808. XA double click on a line is a shortcut for selecting a file and invoking
  1809. Xexplicitly the command \fBView/Edit\fP
  1810. X(if the resource \fBViewEdit\fP is set to "true"
  1811. X.I xbrowser
  1812. Xinvokes the desired editor rather than 
  1813. X.I xmore). 
  1814. X.SH COMMANDS
  1815. X.IP "Quit" 8
  1816. XExits
  1817. X.I xbrowser.
  1818. XWindows created via the Edit or Shell
  1819. Xcommand buttons (
  1820. X.I xterm
  1821. Xwindows) are not deleted.
  1822. XHowever, all dialog boxes and dialog windows are destroyed.
  1823. X.IP "List"
  1824. XSearches directories to list all files which match the pattern
  1825. Xdefined in the File Pattern Box. If a directory is selected in
  1826. Xthe File Window, it is assumed to be the current search directory. If 
  1827. Xthe file selected in the File Window is not a directory, an error message
  1828. Xis returned. If no file is selected or the selected file is not a
  1829. Xdirectory,
  1830. X.I xbrowser
  1831. Xcombines the current working directory with the string specified in the
  1832. XFile Pattern Box to determine the current search directory and 
  1833. Xfile pattern. After the 
  1834. X.I List
  1835. Xcommand is performed successfully, the current directory of 
  1836. X.I xbrowser
  1837. Xis updated (see Directory Label).
  1838. X
  1839. XPressing the left mouse button sorts the files in the ascending order
  1840. Xof the current sorting option (e.g. starting from A to z in case of
  1841. Xfile names). If the middle button is
  1842. Xpressed
  1843. X.I xbrowser
  1844. Xapplies the current sorting option, but in reverse order.
  1845. XIf the right button is pressed, an option menu is displayed for
  1846. Xchoosing the current sorting option, the option to display owner or group
  1847. Xassociated with the file,
  1848. Xand the option to print files starting with a dot or not. The files may
  1849. Xbe sorted by file name, file size or date (in ascending or descending
  1850. Xorder depending if the left or the middle button is pressed). If an option
  1851. Xis selected it is displayed in reverse video.
  1852. X.IP View/Edit
  1853. XInvokes the viewer or the editor on the file selected in the File Window. Only one
  1854. Xfile may be selected at a time. Clicking the left mouse button runs
  1855. Xthe 
  1856. X.I xmore
  1857. Xapplication and loads the selected file. The file cannot be edited.
  1858. XClicking the middle mouse button invokes the preferred editor on
  1859. Xthe selected file. This commands checks the
  1860. Xenvironment variable XEDITOR to determine the preferred editor. If
  1861. Xthe environment variable is not set, 
  1862. X.I xedit
  1863. Xis invoked. 
  1864. X
  1865. XFor each viewer or editor instance a new process and a new X window is
  1866. Xcreated. If the favourite text editor is
  1867. X.I vi
  1868. Xthe environment variable XEDITOR must be set to "xterm -e vi" (which
  1869. Xassures the creation of a new X window). 
  1870. XThe cursor
  1871. Xis always positioned at the beginning of the file.
  1872. X
  1873. XThe Search Commands also include an View/Edit command (left button for
  1874. Xviewer;
  1875. Xmiddle button for editor). It
  1876. Xworks on selections in the Grep Window rather than selections in the
  1877. XFile Window. If the preferred viewer/editor supports line number selection
  1878. Xfrom the command line, such as
  1879. X.I jhsxedit,
  1880. X.I emacs
  1881. Xor
  1882. X.I vi,
  1883. Xthen the cursor of the viewer/editor is positioned at that line of the file 
  1884. Xwhich corresponds to the  grep match displayed
  1885. Xin the grep window. Otherwise the cursor is positioned at the beginning
  1886. Xof the file.
  1887. X.I xmore
  1888. Xand
  1889. X.I xedit
  1890. Xdo not support line positioning.
  1891. X
  1892. XFor both View/Edit commands
  1893. Xthe created windows are not deleted when the user quits
  1894. X.I xbrowser.
  1895. XThe user must close all windows
  1896. Xseparately.
  1897. X.IP Parent
  1898. XClears the File and Grep Window, and changes the current directory
  1899. Xof
  1900. X.I xbrowser
  1901. Xto the parent of the current directory. If the left mouse button is
  1902. Xpressed, the current file pattern is
  1903. Xapplied to list the files of the new current directory using the last sorting option. If the middle button is pressed, the new current
  1904. Xdirectory is \fBnot\fP listed. Pressing the right mouse button
  1905. Xperforms no action; the current directory stays unchanged.
  1906. X.IP Shell
  1907. XProvides the option to execute shell programs or to create
  1908. Xnew xterm windows. 
  1909. X
  1910. XIf the left mouse button is pressed, 
  1911. X.I xbrowser
  1912. Xdisplayes a dialog box in which the user may type a shell command (note
  1913. Xthe execution uses
  1914. X.I sh
  1915. Xrather then
  1916. X.I csh;
  1917. Xcertain special characters, such as ~ are not valid for
  1918. X.I sh).
  1919. XIf the user selected one or several files in the File Window, their
  1920. Xnames are displayed in the dialog box. The dialog window also displays
  1921. X2 options: 
  1922. X.B Return Ouput
  1923. Xand
  1924. X.B Return Diagnostics.
  1925. XIn the first case the standard output generated by the shell command
  1926. Xis displayed in the Message window (if the
  1927. Xinformation consists only of a few lines) or in a separate popup window; in the second case the standard error information is returned to the user. 
  1928. XBoth buttons are
  1929. Xtoggles and the user may enable/disable them. If an option is
  1930. Xselected, it is displayed in reverse video. 
  1931. XIf the user disables both options, messages are displayed in the 
  1932. X.I xterm
  1933. Xstartup window. The user must 
  1934. Xquit the popup window, before he/she may invoke new commands in
  1935. X.I xbrowser.
  1936. X
  1937. XIf the middle button is pressed a new
  1938. X.I xterm
  1939. Xwindow is created inheriting the current working directory
  1940. Xof
  1941. X.I xbrowser.
  1942. XIf the user quits
  1943. X.I xbrowser, xterm
  1944. Xwindows are not deleted. They must be closed separately.
  1945. X.IP Copy
  1946. XCopies files selected in the File Window. The user is 
  1947. Xprompted in a dialog box to specify the target file or target
  1948. Xdirectory. The File Window is updated.
  1949. X.IP Move
  1950. XMoves files selected in the File Window. The user is 
  1951. Xprompted in a dialog box to specify the target file or target
  1952. Xdirectory. The File Window is updated.
  1953. X.IP Delete
  1954. XDeletes files selected in the File Window. For each file the user
  1955. Xis prompted in a dialog box, if he/she wants to delete this file
  1956. X(yes button) or skip this file (no button) or cancel the delete
  1957. Xoperation (cancel button). If the user selects the cancel button
  1958. Xduring the interaction, the Delete command is aborted and no file
  1959. Xis deleted (even if the user answered yes to previous prompts).
  1960. XThe actual deletion occurs after the user answered all prompts with
  1961. Xyes or no.
  1962. X.IP Grep
  1963. XSearches files to find lines 
  1964. Xwhich match the pattern defined in the string box after the 
  1965. X.I Grep 
  1966. Xcommand. The files searched is determined by the 
  1967. Xpattern in the File Pattern Box, the files selected in the File Window
  1968. Xand selections in the dialog box associated with
  1969. X.I Grep
  1970. X(the dialog box is invoked by pressing the right mouse button; see below).
  1971. XAll files selected in the File Window which
  1972. Xsatisfy the file pattern in the File Pattern Box are searched.
  1973. XIf no file is selected in the File Window, all files which satisfy
  1974. Xthe file pattern are
  1975. Xsearched. The search pattern for
  1976. X.I Grep
  1977. Xis a regular expression as defined by the
  1978. X.I grep
  1979. Xshell command.
  1980. X.I xbrowser
  1981. Xattempts to determine the file type (executable, text, etc). Only
  1982. Xtext files are searched. This allows the user to extend the file
  1983. Xselection across non-text files (e.g., select all .c and .o files
  1984. Xin a directory; but .o files are not searched).
  1985. X
  1986. XClicking the left mouse button
  1987. Xcontinues until all files which match the file pattern are searched.
  1988. XClicking the middle
  1989. Xbutton stops searching at the first file which contains a match
  1990. Xfor the string to be searched.
  1991. X
  1992. XClicking the right button displays a dialog window which allows the
  1993. Xuser to specify the search behavior in case
  1994. X.I Grep
  1995. Xencounters a directory. The user may skip all directories
  1996. X(this is the default)
  1997. Xthat means only files selected in the File Window are searched.
  1998. XThe user may select the option
  1999. X"search next-level directory" which specifies that all directories
  2000. Xwhich are selected in the File Window are searched, i.e. files in
  2001. Xthese directories
  2002. Xwhose file names satisfy the pattern in the File Pattern Box. The last
  2003. Xoption allows the user to recursively search all directories which
  2004. Xare encountered.
  2005. X.I Grep
  2006. Xfor this option may take a long time (depending on the size of the
  2007. Xunderlying directory structure).
  2008. XThe file pattern in the File Pattern Box is only 
  2009. Xinterpreted for the files which are actually searched for
  2010. Xthe string pattern. It is not a selection criteria for directory
  2011. Xnames.
  2012. X
  2013. XThe dialog window for
  2014. X.I Grep
  2015. Xalso supports a toggle for case-sensitive or case insensitive search.
  2016. XThe default setting is case-sensitive.
  2017. X.SH X DEFAULTS
  2018. X.I xbrowser
  2019. Xsupports the following resource which may be set in the .Xdefaults file:
  2020. X.IP "ViewEdit"
  2021. Xspecifies the tool to be invoked after the user double-clicks a text file
  2022. Xof the File Window or the Grep Window. If the resource is set to "false"
  2023. X.I xbrowser
  2024. Xinvokes
  2025. X.I xmore
  2026. Xon the double-clicked file (the default setting of ViewEdit is false).
  2027. XOtherwise
  2028. X.I xbrowser
  2029. Xinvokes the user desired editor on the double-clicked file.
  2030. X.SH FILES
  2031. X~/.XtActions, ~/.Xdefaults
  2032. X.br
  2033. X/usr/lib/X11/.XtActions
  2034. X.SH SEE ALSO
  2035. XX(1), xedit(1), ls(1), grep(1), sh(1), csh(1), jhsxedit(1);
  2036. X.SH BUGS
  2037. XBeware of using the geometry resource in your .Xdefaults file for
  2038. X.I xbrowser.
  2039. XThe
  2040. Xtoolkit obviously interprets these values not only for the toplevel
  2041. Xwindows but also for the popup windows (dialog boxes). I tried
  2042. Xto overwrite the values, but it does not work consistently. If 
  2043. Xyou specify a geometry resource for
  2044. X.I xbrowser
  2045. Xin your .Xdefaults file, the dialog boxes will have initially these geometry
  2046. Xsizes (you might have very strange shaped command buttons). Geometry values
  2047. Xspecified on the command line which called 
  2048. X.I xbrowser 
  2049. Xdo not affect the dialog
  2050. Xbox geometry.
  2051. X
  2052. XIf you use the window manager twm, your .twmrc must set 
  2053. X.I NoTitleFocus
  2054. Xotherwise the dialog boxes and the text windows do not work
  2055. Xcorrectly. There is a bug in twm.
  2056. X.SH RESTRICTIONS
  2057. X.SH COPYRIGHT
  2058. XCopyright 1988, Xerox Corporation.
  2059. X.SH AUTHOR
  2060. XHans Schlichter, Xerox Corporation.
  2061. END_OF_FILE
  2062. if test 13458 -ne `wc -c <'xbrowser.man'`; then
  2063.     echo shar: \"'xbrowser.man'\" unpacked with wrong size!
  2064. fi
  2065. # end of 'xbrowser.man'
  2066. fi
  2067. echo shar: End of archive 1 \(of 3\).
  2068. cp /dev/null ark1isdone
  2069. MISSING=""
  2070. for I in 1 2 3 ; do
  2071.     if test ! -f ark${I}isdone ; then
  2072.     MISSING="${MISSING} ${I}"
  2073.     fi
  2074. done
  2075. if test "${MISSING}" = "" ; then
  2076.     echo You have unpacked all 3 archives.
  2077.     rm -f ark[1-9]isdone
  2078. else
  2079.     echo You still need to unpack the following archives:
  2080.     echo "        " ${MISSING}
  2081. fi
  2082. ##  End of shell archive.
  2083. exit 0
  2084. -- 
  2085. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  2086. Moderator of comp.sources.x
  2087.